/**   
 * @{#} ObjMetaCenter.java Create on 2013-6-19 上午9:56:15   
 *   
 * Copyright (c) 2012 by Baidu.   
 */
package objtable.core;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Joiner;

import objtable.algm.Algm1Row;
import objtable.algm.Algm2Row;
import objtable.algm.Algm3Row;
import objtable.algm.AlgmSelector;
import objtable.algm.ComputeBy;
import objtable.algm.GroupBy;
import objtable.algm.OrderBy;
import objtable.engine.xmlnode.gen.Param;
import objtable.struct.Row;

/**
 * @author <a href="mailto:zhangbo07@baidu.com">zhangbo07</a>
 * @version 1.0
 */

public class TableCenter {
	private static HashMap<String, TableGenerator> hm_name2table = new HashMap<String, TableGenerator>();

	private static HashMap<String, List<Row>> hm_name2list = new HashMap<String, List<Row>>();

	private static Logger log = LoggerFactory.getLogger(TableCenter.class);

	private static DecimalFormat df = new DecimalFormat("0.0000");

	private TableCenter() {
	}

	public final static void putTable(String tablename, TableGenerator tg) {
		hm_name2table.put(tablename, tg);
	}

	public final static TableGenerator getTable(String name) {
		return hm_name2table.get(name);
	}

	public final static List<Row> getTableData(String tablename) {
		return hm_name2list.get(tablename);
	}

	public final static void putTableData(String tablename, List<Row> data) {
		hm_name2list.put(tablename, data);
	}

	@SuppressWarnings("unchecked")
	public final static List<Row> filterTableData(String table,
			String simpleExpress) {
		Algm1Row fb = AlgmSelector.getFilterBy(simpleExpress,
				TableCenter.getTableData(table));
		return (List<Row>) fb.execute(TableCenter.getTableData(table));
	}

	// 注册的时候只有函数名，内部生成（对象名.函数名<-->函数名)的映射关系
	public final static void regComputeFunc(String funcname, Object obj) {
		ScriptEnv.regComputeFunc(funcname, obj);
	}

	@SuppressWarnings("unchecked")
	public final static List<Row> computeTableData(String table,
			String complexExpress) {
		ComputeBy cb = new ComputeBy(complexExpress);
		return (List<Row>) cb.execute(TableCenter.getTableData(table));
	}

	@SuppressWarnings("unchecked")
	public final static List<Row> groupTableData(String table,
			String groupfields, String sumfields, String newtable) {
		GroupBy gb = new GroupBy(groupfields, sumfields);
		List<Row> result = (List<Row>) gb.execute(TableCenter
				.getTableData(table));
		TableCenter.putTable(newtable, gb.getGroupTableGenerator());
		TableCenter.putTableData(newtable, result);
		return result;
	}

	public final static void matchTableData(String tablea, String tableb,
			String condition, String express) {
		Algm2Row cb = AlgmSelector.getMatchBy(condition, express);
		cb.execute(TableCenter.getTableData(tablea),
				TableCenter.getTableData(tableb));
	}

	public final static void joinTableData(String tablea, String tableb,
			String tablec, String condition, String express, boolean append) {
		Algm3Row cb = AlgmSelector.getJoinBy(condition, express, append);
		cb.execute(TableCenter.getTableData(tablea),
				TableCenter.getTableData(tableb), tablec);
	}

	@SuppressWarnings("unchecked")
	public final static List<Row> orderTableData(String table, String fields,
			boolean asc) {
		OrderBy ob = new OrderBy(fields, asc);
		return (List<Row>) ob.execute(TableCenter.getTableData(table));
	}

	public final static String getValueString(Row r, Param p) {
		switch (p.getType()) {
		case INT:
			return String.valueOf(r.getInt(p.getValue()));
		case DOUBLE:
			return String.valueOf(df.format(r.getDouble(p.getValue())));
		case LONG:
			return String.valueOf(r.getLong(p.getValue()));
		case STRING:
			return r.getString(p.getValue());
		}
		return "";
	}

	// 供Debug使用,field可以用，号隔开
	public final static void printTableData(String table, String field) {
		List<Row> l = TableCenter.getTableData(table);
		Joiner j = Joiner.on(",");
		ArrayList<String> al = new ArrayList<String>();
		String[] ss = field.split(",");
		log.info("Table:" + table + " Field:" + field);
		for (Row r : l) {
			al.clear();
			for (String s : ss) {
				al.add(s + ":" + r.get(field));
			}
			log.info(j.join(al));
		}
	}
}
